package edu.cicese.alz.swing;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.LineBorder;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

/**
 * Created by: Eduardo Quintana Contreras
 * Date: 28/06/12
 * Time: 12:18 AM
 */
public class ColorPopup extends JPanel {

	private JLabel lblPreview;
	private MainSwatchPanel swatchPanel;
	private RecentSwatchPanel recentSwatchPanel;
	private Color selectedColor;
	private JPopupMenu popup;

	public ColorPopup(JPopupMenu popup, Color color) {
		setLayout(new BorderLayout());
		this.popup = popup;
		initComponents(color);
	}

	private void initComponents(Color color) {
		lblPreview = SwingUtil.createLabel("", 60, 60);
		lblPreview.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.BLACK),
				BorderFactory.createLineBorder(Color.WHITE)));
		lblPreview.setOpaque(true);
		lblPreview.setBackground(color);


		swatchPanel = new MainSwatchPanel();
		recentSwatchPanel = new RecentSwatchPanel();

//		MainSwatchListener mainSwatchListener = new MainSwatchListener();
		swatchPanel.addMouseListener(new MainSwatchListener());
		swatchPanel.addMouseMotionListener(new SwatchListener());
//		RecentSwatchListener recentSwatchListener = new RecentSwatchListener();
		recentSwatchPanel.addMouseListener(new RecentSwatchListener());
		recentSwatchPanel.addMouseMotionListener(new SwatchListener());

		JPanel mainHolder = new JPanel(new BorderLayout());
		Border border = new CompoundBorder(new LineBorder(Color.BLACK),
				new LineBorder(Color.WHITE));
		mainHolder.setBorder(border);
		mainHolder.add(swatchPanel, BorderLayout.CENTER);

		JLabel lblRecent = new JLabel("Recent:");
		lblRecent.setLabelFor(recentSwatchPanel);

		JPanel recentHolder = new JPanel(new BorderLayout());
		recentHolder.setBorder(border);
		recentHolder.add(recentSwatchPanel, BorderLayout.CENTER);

		/*Box boxSwatches = Box.createHorizontalBox();
		boxSwatches.add(Box.createHorizontalStrut(10));
		boxSwatches.add(mainHolder);
		boxSwatches.add(Box.createHorizontalStrut(10));
		boxSwatches.add(recentHolder);
		boxSwatches.add(Box.createHorizontalStrut(10));
		boxSwatches.add(lblPreview);
		boxSwatches.add(Box.createHorizontalStrut(10));*/


		JPanel pSwatches = new JPanel(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();

		gbc.anchor = GridBagConstraints.LAST_LINE_START;
		gbc.gridwidth = 1;
		gbc.gridheight = 2;
		gbc.insets = new Insets(0, 0, 0, 10);
		pSwatches.add(mainHolder, gbc);

		gbc.insets = new Insets(0, 0, 0, 0);
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		gbc.gridheight = 1;
		gbc.weighty = 1.0;
		pSwatches.add(lblRecent, gbc);

		gbc.weighty = 0;
		gbc.gridheight = GridBagConstraints.REMAINDER;
		pSwatches.add(recentHolder, gbc);

		Box boxMain = Box.createHorizontalBox();
		boxMain.add(pSwatches);
		boxMain.add(Box.createHorizontalStrut(10));
		boxMain.add(lblPreview);

		add(boxMain);
	}

	public Color getSelectedColor() {
		return selectedColor;
	}

	public void setSelectedColor(Color selectedColor) {
		this.selectedColor = selectedColor;
	}

	class RecentSwatchListener extends MouseAdapter {
		public void mousePressed(MouseEvent e) {
			setSelectedColor(recentSwatchPanel.getColorForLocation(e.getX(), e.getY()));
			popup.setVisible(false);
			if (isEnabled()) {
//					Color markerBackground = recentSwatchPanel.getColorForLocation(e.getX(), e.getY());
//					setSelectedColor(markerBackground);
			}
		}
	}

	class MainSwatchListener extends MouseAdapter {
		public void mousePressed(MouseEvent e) {
			setSelectedColor(swatchPanel.getColorForLocation(e.getX(), e.getY()));
			if (isEnabled()) {
//					Color markerBackground = swatchPanel.getColorForLocation(e.getX(), e.getY());
//					setSelectedColor(markerBackground);
//					recentSwatchPanel.setMostRecentColor(markerBackground);
			}
		}
	}

	class SwatchListener implements MouseMotionListener {
		@Override
		public void mouseDragged(MouseEvent e) {}

		@Override
		public void mouseMoved(MouseEvent e) {
			lblPreview.setBackground(swatchPanel.getColorForLocation(e.getX(), e.getY()));
		}
	}


	class SwatchPanel extends JPanel {

		protected Color[] colors;
		protected Dimension swatchSize;
		protected Dimension numSwatches;
		protected Dimension gap;

		public SwatchPanel() {
			initValues();
			initColors();
			setToolTipText(""); // register for events
			setOpaque(true);
			setBackground(Color.white);
			setRequestFocusEnabled(false);
			setInheritsPopupMenu(true);
		}

		public boolean isFocusTraversable() {
			return false;
		}

		protected void initValues() {

		}

		public void paintComponent(Graphics g) {
			g.setColor(getBackground());
			g.fillRect(0, 0, getWidth(), getHeight());
			for (int row = 0; row < numSwatches.height; row++) {
				int y = row * (swatchSize.height + gap.height);
				for (int column = 0; column < numSwatches.width; column++) {

					g.setColor(getColorForCell(column, row));
					int x;
					if ((!this.getComponentOrientation().isLeftToRight()) &&
							(this instanceof RecentSwatchPanel)) {
						x = (numSwatches.width - column - 1) * (swatchSize.width + gap.width);
					} else {
						x = column * (swatchSize.width + gap.width);
					}
					g.fillRect(x, y, swatchSize.width, swatchSize.height);
					g.setColor(Color.black);
					g.drawLine(x + swatchSize.width - 1, y, x + swatchSize.width - 1, y + swatchSize.height - 1);
					g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1, y + swatchSize.height - 1);
				}
			}
		}

		public Dimension getPreferredSize() {
			int x = numSwatches.width * (swatchSize.width + gap.width) - 1;
			int y = numSwatches.height * (swatchSize.height + gap.height) - 1;
			return new Dimension(x, y);
		}

		protected void initColors() {


		}

		public String getToolTipText(MouseEvent e) {
			Color color = getColorForLocation(e.getX(), e.getY());
			return color.getRed() + ", " + color.getGreen() + ", " + color.getBlue();
		}

		public Color getColorForLocation(int x, int y) {
			int column;
			if ((!this.getComponentOrientation().isLeftToRight()) &&
					(this instanceof RecentSwatchPanel)) {
				column = numSwatches.width - x / (swatchSize.width + gap.width) - 1;
			} else {
				column = x / (swatchSize.width + gap.width);
			}
			int row = y / (swatchSize.height + gap.height);
			return getColorForCell(column, row);
		}

		private Color getColorForCell(int column, int row) {
			return colors[(row * numSwatches.width) + column]; // (STEVE) - change data orientation here
		}


	}

	class RecentSwatchPanel extends SwatchPanel {
		protected void initValues() {
			swatchSize = UIManager.getDimension("ColorChooser.swatchesRecentSwatchSize", getLocale());
			numSwatches = new Dimension(5, 7);
			gap = new Dimension(1, 1);
		}


		protected void initColors() {
			Color defaultRecentColor = UIManager.getColor("ColorChooser.swatchesDefaultRecentColor", getLocale());
			int numColors = numSwatches.width * numSwatches.height;

			colors = new Color[numColors];
			for (int i = 0; i < numColors; i++) {
				colors[i] = defaultRecentColor;
			}
		}

		public void setMostRecentColor(Color c) {
			System.arraycopy(colors, 0, colors, 1, colors.length - 1);
			colors[0] = c;
			repaint();
		}

	}

	class MainSwatchPanel extends SwatchPanel {

		protected void initValues() {
			swatchSize = UIManager.getDimension("ColorChooser.swatchesSwatchSize", getLocale());
			numSwatches = new Dimension(31, 9);
			gap = new Dimension(1, 1);
		}

		protected void initColors() {
			int[] rawValues = initRawValues();
			int numColors = rawValues.length / 3;

			colors = new Color[numColors];
			for (int i = 0; i < numColors; i++) {
				colors[i] = new Color(rawValues[(i * 3)], rawValues[(i * 3) + 1], rawValues[(i * 3) + 2]);
			}
		}

		private int[] initRawValues() {
			int[] rawValues = {
					255, 255, 255, // first row.
					204, 255, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					204, 204, 255,
					255, 204, 255,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 204, 204,
					255, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 255, 204,
					204, 204, 204,  // second row.
					153, 255, 255,
					153, 204, 255,
					153, 153, 255,
					153, 153, 255,
					153, 153, 255,
					153, 153, 255,
					153, 153, 255,
					153, 153, 255,
					153, 153, 255,
					204, 153, 255,
					255, 153, 255,
					255, 153, 204,
					255, 153, 153,
					255, 153, 153,
					255, 153, 153,
					255, 153, 153,
					255, 153, 153,
					255, 153, 153,
					255, 153, 153,
					255, 204, 153,
					255, 255, 153,
					204, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 153,
					153, 255, 204,
					204, 204, 204,  // third row
					102, 255, 255,
					102, 204, 255,
					102, 153, 255,
					102, 102, 255,
					102, 102, 255,
					102, 102, 255,
					102, 102, 255,
					102, 102, 255,
					153, 102, 255,
					204, 102, 255,
					255, 102, 255,
					255, 102, 204,
					255, 102, 153,
					255, 102, 102,
					255, 102, 102,
					255, 102, 102,
					255, 102, 102,
					255, 102, 102,
					255, 153, 102,
					255, 204, 102,
					255, 255, 102,
					204, 255, 102,
					153, 255, 102,
					102, 255, 102,
					102, 255, 102,
					102, 255, 102,
					102, 255, 102,
					102, 255, 102,
					102, 255, 153,
					102, 255, 204,
					153, 153, 153, // fourth row
					51, 255, 255,
					51, 204, 255,
					51, 153, 255,
					51, 102, 255,
					51, 51, 255,
					51, 51, 255,
					51, 51, 255,
					102, 51, 255,
					153, 51, 255,
					204, 51, 255,
					255, 51, 255,
					255, 51, 204,
					255, 51, 153,
					255, 51, 102,
					255, 51, 51,
					255, 51, 51,
					255, 51, 51,
					255, 102, 51,
					255, 153, 51,
					255, 204, 51,
					255, 255, 51,
					204, 255, 51,
					153, 255, 51,
					102, 255, 51,
					51, 255, 51,
					51, 255, 51,
					51, 255, 51,
					51, 255, 102,
					51, 255, 153,
					51, 255, 204,
					153, 153, 153, // Fifth row
					0, 255, 255,
					0, 204, 255,
					0, 153, 255,
					0, 102, 255,
					0, 51, 255,
					0, 0, 255,
					51, 0, 255,
					102, 0, 255,
					153, 0, 255,
					204, 0, 255,
					255, 0, 255,
					255, 0, 204,
					255, 0, 153,
					255, 0, 102,
					255, 0, 51,
					255, 0, 0,
					255, 51, 0,
					255, 102, 0,
					255, 153, 0,
					255, 204, 0,
					255, 255, 0,
					204, 255, 0,
					153, 255, 0,
					102, 255, 0,
					51, 255, 0,
					0, 255, 0,
					0, 255, 51,
					0, 255, 102,
					0, 255, 153,
					0, 255, 204,
					102, 102, 102, // sixth row
					0, 204, 204,
					0, 204, 204,
					0, 153, 204,
					0, 102, 204,
					0, 51, 204,
					0, 0, 204,
					51, 0, 204,
					102, 0, 204,
					153, 0, 204,
					204, 0, 204,
					204, 0, 204,
					204, 0, 204,
					204, 0, 153,
					204, 0, 102,
					204, 0, 51,
					204, 0, 0,
					204, 51, 0,
					204, 102, 0,
					204, 153, 0,
					204, 204, 0,
					204, 204, 0,
					204, 204, 0,
					153, 204, 0,
					102, 204, 0,
					51, 204, 0,
					0, 204, 0,
					0, 204, 51,
					0, 204, 102,
					0, 204, 153,
					0, 204, 204,
					102, 102, 102, // seventh row
					0, 153, 153,
					0, 153, 153,
					0, 153, 153,
					0, 102, 153,
					0, 51, 153,
					0, 0, 153,
					51, 0, 153,
					102, 0, 153,
					153, 0, 153,
					153, 0, 153,
					153, 0, 153,
					153, 0, 153,
					153, 0, 153,
					153, 0, 102,
					153, 0, 51,
					153, 0, 0,
					153, 51, 0,
					153, 102, 0,
					153, 153, 0,
					153, 153, 0,
					153, 153, 0,
					153, 153, 0,
					153, 153, 0,
					102, 153, 0,
					51, 153, 0,
					0, 153, 0,
					0, 153, 51,
					0, 153, 102,
					0, 153, 153,
					0, 153, 153,
					51, 51, 51, // eigth row
					0, 102, 102,
					0, 102, 102,
					0, 102, 102,
					0, 102, 102,
					0, 51, 102,
					0, 0, 102,
					51, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 102,
					102, 0, 51,
					102, 0, 0,
					102, 51, 0,
					102, 102, 0,
					102, 102, 0,
					102, 102, 0,
					102, 102, 0,
					102, 102, 0,
					102, 102, 0,
					102, 102, 0,
					51, 102, 0,
					0, 102, 0,
					0, 102, 51,
					0, 102, 102,
					0, 102, 102,
					0, 102, 102,
					0, 0, 0, // ninth row
					0, 51, 51,
					0, 51, 51,
					0, 51, 51,
					0, 51, 51,
					0, 51, 51,
					0, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 51,
					51, 0, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					51, 51, 0,
					0, 51, 0,
					0, 51, 51,
					0, 51, 51,
					0, 51, 51,
					0, 51, 51,
					51, 51, 51};
			return rawValues;
		}
	}
}
